package org.aiesec.fortaleza.xmatch.controller.aspect;

import java.lang.reflect.Field;

import org.aiesec.fortaleza.xmatch.controller.annotation.ServiceIn;
import org.aiesec.fortaleza.xmatch.model.repository.Repository;
import org.aiesec.fortaleza.xmatch.model.service.Service;
import org.aiesec.fortaleza.xmatch.model.util.ReflectionUtil;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.jboss.seam.Component;

@Aspect
public class InjectService {

	@After(value = "initialization(public org.aiesec.fortaleza.xmatch.controller.action..*.new (..))")
	public void injectServiceAfter(JoinPoint thisJoinPoint) {
		inject(thisJoinPoint);

	}

	private void inject(JoinPoint thisJoinPoint) {
		Object obj = thisJoinPoint.getThis();
		if (obj.getClass().isAnnotationPresent(ServiceIn.class)) {
			ServiceIn serviceIn = obj.getClass().getAnnotation(ServiceIn.class);
			try {
				Object service = getService(serviceIn);
				ReflectionUtil.setMethodValue(obj, "setService", service,
						Service.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		for (Field field : obj.getClass().getDeclaredFields()) {
			if (field.isAnnotationPresent(ServiceIn.class)) {
				try {
					ServiceIn serviceIn = field.getAnnotation(ServiceIn.class);
					Object service = getService(serviceIn);
					field.setAccessible(true);
					field.set(obj, service);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	private Object getService(ServiceIn serviceIn) throws Exception {
		Object service = Component.getInstance(serviceIn.name(), true);
		Object repository = Component.getInstance(serviceIn.repository(), true);
		ReflectionUtil.setMethodValue(repository, "setPersistentClass",
				serviceIn.persistenceClass(), Class.class);
		ReflectionUtil.setMethodValue(service, "setRepository", repository,
				Repository.class);
		return service;
	}
}
